package com.origin.src.datasource.sharding.algorithm;

import com.google.common.base.Strings;
import org.apache.shardingsphere.infra.datanode.DataNodeInfo;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Properties;
import java.util.zip.CRC32;
import java.util.zip.Checksum;


public abstract class ChecksumModShardingAlgorithm implements StandardShardingAlgorithm<Comparable<?>>
//        , ShardingAutoTableAlgorithm
{

    public static final String SHARDING_COUNT_KEY = "sharding-count";

//    @Getter
//    private int shardingCount;


    @Override
    public void init(final Properties properties) {
//        if (properties == null || properties.getProperty(SHARDING_COUNT_KEY) == null) {
//            throw new MissingRequiredShardingConfigurationException(SHARDING_COUNT_KEY);
//        }
//        this.shardingCount = Integer.parseInt(properties.getProperty(SHARDING_COUNT_KEY));
    }

    /**
     * Get auto tables amount.
     *
     * @return the auto tables amount
     */
//    @Override
//    public int getAutoTablesAmount() {
//        return shardingCount;
//    }
    public abstract Checksum getChecksum();


    /**
     * Sharding.
     *
     * @param availableTargetNames available data sources or table names
     * @param shardingValue        sharding value
     * @return sharding result for data source or table name
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Comparable<?>> shardingValue) {
        String key = String.valueOf(shardingValue.getValue());
        Checksum checksum = getChecksum();
        checksum.update(key.getBytes(StandardCharsets.UTF_8));
        String suffix = Long.toString(checksum.getValue() % availableTargetNames.size());
        DataNodeInfo dataNodeInfo = shardingValue.getDataNodeInfo();
        return dataNodeInfo.getPrefix() + Strings.padStart(suffix, dataNodeInfo.getSuffixMinLength(), dataNodeInfo.getPaddingChar());
    }

    /**
     * Sharding.
     *
     * @param availableTargetNames available data sources or table names
     * @param shardingValue        sharding value
     * @return sharding results for data sources or table names
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Comparable<?>> shardingValue) {
        return availableTargetNames;
    }


}
